feat(metrics): add public constructors for metric data types#3489
feat(metrics): add public constructors for metric data types#3489darklight3it wants to merge 5 commits intoopen-telemetry:mainfrom
Conversation
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3489 +/- ##
=======================================
+ Coverage 83.7% 84.4% +0.7%
=======================================
Files 126 126
Lines 25386 25825 +439
=======================================
+ Hits 21255 21818 +563
+ Misses 4131 4007 -124 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
f3fc113 to
d3e1646
Compare
|
@darklight3it - Can you clarify the intended use case for constructing In the normal metrics pipeline, instrumentation libraries create measurements through instruments, and the SDK/MetricReader produces Is the target use case pre-aggregated metrics from an external source, or directly sending measurements to an exporter while bypassing SDK aggregation? If it is the latter, I am not sure |
|
Yes, the target use case is pre-aggregated metrics from an external source. The aggregation is already done, the Rust side only needs to serialize and transport the resulting The challenge I'm running into is that This makes it difficult to use the exporter trait independently of the SDK's internal reader pipeline. I think opening up |
|
Thanks, that use case makes sense. I think this is closer to the spec’s That makes me hesitant to expose constructors for the full ResourceMetrics tree and encourage calling |
|
Thanks @lalitb for the thoughtful feedback, I appreciate the discussion. On
On the concern about opening up the full
|
|
I think The “pull” part there is only inside the SDK: the MetricReader asks the producer for already-aggregated data. It does not mean the final export has to be pull-based. The final exporter can still be a push exporter sending OTLP. So the shape would be: external pre-aggregated source -> MetricProducer -> MetricReader -> PushMetricExporter. For the immediate-export case, we may need an API that lets the reader collect/export on demand, but I do not think that means |
|
I understand the preference for an internal path, but if I'm reading the proposed workflow correctly, the changes in this PR are still necessary for that to work. // simplified MetricProducer shape to illustrate the point
struct MyProducer { buffer: Mutex<Vec<ScopeMetrics>> }
impl MetricProducer for MyProducer {
fn produce(&self) -> Vec<ScopeMetrics> {
self.buffer.lock().unwrap().drain(..).collect()
}
}
fn receive_external_metrics(data: ExternalData) {
let scope_metrics: Vec<ScopeMetrics> = data.into(); // needs constructors for
// ScopeMetrics, Metric,
// Sum/Gauge/Histogram,
// DataPoint
PRODUCER.buffer.lock().unwrap().extend(scope_metrics);
READER.force_collect(); // on-demand collect to control when data is flushed
}Either way, users will need a supported way to create these types from external data, which means exposing some form of construction contract. We could introduce a parallel set of public DTO types and map them to the The same reasoning applies to the |
Fixes #3469
Changes
Added public constructors to metric data types, allowing users to use the public
PushMetricExporter::export.Rationale:
builderpattern, where the builder explicitly lists mandatory fields. This matches the established pattern inopentelemetry-sdk,opentelemetry-otlp, and other crates.newmethod.Summary:
with_*) fieldsResourceMetricsbuilder()resource,scope_metricsScopeMetricsbuilder()scope,metricsMetricbuilder(name, data)name,datadescription,unitGauge<T>builder(data_points, time)data_points,timestart_timeGaugeDataPoint<T>builder(value)valueattributes,exemplarsSum<T>new(...)data_points,temporality,is_monotonic,start_time,timeSumDataPoint<T>builder(value)valueattributes,exemplarsHistogram<T>new(...)data_points,temporality,start_time,timeHistogramDataPoint<T>builder(count, sum, bounds, bucket_counts)count,sum,bounds,bucket_countsattributes,min,max,exemplarsExponentialHistogram<T>new(...)data_points,temporality,start_time,timeExponentialHistogramDataPoint<T>builder(count, sum, scale, zero_count, positive_bucket, negative_bucket)count,sum,scale,zero_count,positive_bucket,negative_bucketattributes,min,max,zero_threshold,exemplarsExponentialBucketnew(offset, counts)offset,countsExemplar<T>builder(value, time)value,timefiltered_attributes,span_id,trace_idExample usage:
Merge requirement checklist
CHANGELOG.mdfiles updated for non-trivial, user-facing changes